home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / MacHacksBug / Python 1.5.2c1 / Mac / scripts / binhextree.py next >
Encoding:
Text File  |  2000-06-23  |  5.3 KB  |  241 lines

  1. #
  2. # binhextree - Recursively descend a directory and
  3. # pack all resource files.
  4. #
  5. # Actually it doesn't binhex anymore, it only copies projects.
  6. #
  7. # Jack Jansen, CWI, August 1995.
  8. #
  9.  
  10. import os
  11. import binhex
  12. import sys
  13. import macostools
  14. import macfs
  15.  
  16. import aetools
  17. from Metrowerks_Shell_Suite import Metrowerks_Shell_Suite
  18. from Required_Suite import Required_Suite 
  19.  
  20. class MwShell(aetools.TalkTo, Metrowerks_Shell_Suite, Required_Suite):
  21.     pass
  22.  
  23. # Top-level directory
  24. TOP=''
  25.  
  26. # Where to put CW projects, relative to TOP
  27. CWDIR=':Mac:mwerks:projects'
  28. # From which folders to put projects there
  29. CWDIRDIRS=['build.mac', 'build.macstand', 'build.macfreeze', 'PlugIns']
  30.  
  31. # Helper routines
  32. def binhexit(path, name):
  33.     dstfile = path + '.hqx'
  34.     if os.path.exists(dstfile):
  35.         print 'Compare', path,'...',
  36.         if binhexcompare(path, dstfile):
  37.             print 'Identical, skipped.'
  38.             return
  39.         else:
  40.             print 'Not up-to-date.'
  41.     print 'Binhexing', path
  42.     binhex.binhex(path, dstfile)
  43.     
  44. def binhexcompare(source, hqxfile):
  45.     """(source, hqxfile) - Check whether the two files match (forks only)"""
  46.     ifp = binhex.HexBin(hqxfile)
  47.  
  48.     sfp = open(source, 'rb')
  49.     while 1:
  50.         d = ifp.read(128000)
  51.         d2 = sfp.read(128000)
  52.         if d <> d2:
  53.             return 0
  54.         if not d: break
  55.     sfp.close()
  56.     ifp.close_data()
  57.     
  58.     d = ifp.read_rsrc(128000)
  59.     if d:
  60.         sfp = binhex.openrsrc(source, 'rb')
  61.         d2 = sfp.read(128000)
  62.         if d <> d2:
  63.             return 0
  64.         while 1:
  65.             d = ifp.read_rsrc(128000)
  66.             d2 = sfp.read(128000)
  67.             if d <> d2:
  68.                 return 0
  69.             if not d: break
  70.     return 1
  71.  
  72. # Project files to handle
  73. project_files = {}
  74.  
  75. def hexbincwprojects(creator):
  76.     """Compact and hexbin all files remembered with a given creator"""
  77.     cw_running = 0
  78.     for fss in project_files[creator]:
  79.         srcfile = fss.as_pathname()
  80.         
  81.         old_style = 0
  82.         if srcfile[-1] == 'µ':
  83.             dstfile = srcfile[:-1]+'mu.hqx'
  84.             old_style = 1
  85.         elif srcfile[-3] == '.mu':
  86.             dstfile = srcfile + '.hqx'
  87.         elif ord(srcfile[-1]) >= 128:
  88.             dstfile = srcfile[:-1]+`ord(srcfile[-1])`+'.hqx'
  89.         else:
  90.             dstfile = srcfile + '.hqx'
  91.             
  92.         if os.path.exists(dstfile) and \
  93.                 os.stat(dstfile)[8] >= os.stat(srcfile)[8]:
  94.             print 'Skip', dstfile,'- Up-to-date'
  95.             continue
  96.         print 'Compacting', dstfile
  97.         if old_style:
  98.             if not cw_running:
  99.                 try:
  100.                     mgr = MwShell(creator, start=1)
  101.                 except 'foo':
  102.                     print 'Not handled:', creator
  103.                     return
  104.                 cw_running = 1
  105.             mgr.open(fss)
  106.             mgr.Reset_File_Paths()
  107.             mgr.Remove_Binaries()
  108.             mgr.Close_Project()
  109.         
  110.         print 'Binhexing', dstfile
  111.         binhex.binhex(srcfile, dstfile)
  112.     if cw_running:
  113.         mgr.quit()
  114.     
  115. def copycwproject(path, name):
  116.     """Copy CW project (if needed) and remember for hexbinning"""
  117.     global project_files
  118.     
  119.     dstdir = os.path.join(TOP, CWDIR)
  120.     if path[:len(dstdir)] == dstdir:
  121.         return
  122.     srcdir = os.path.split(path)[0]
  123.     srcdir = os.path.split(srcdir)[1]
  124.     if srcdir in CWDIRDIRS:
  125.         if not os.path.exists(dstdir):
  126.             print dstdir
  127.             print 'No CW-project dir, skip', name
  128.             return
  129.         dstfile = os.path.join(dstdir, os.path.join(srcdir, name))
  130.     else:
  131.         if path[-2:] == '.µ':
  132.             dstfile = path[:-2]+ '.mu'
  133.         elif path[-4:] == '.prj':
  134.             dstfile = None
  135.         else:
  136.             return
  137.  
  138.     if dstfile:
  139.         # If the destination doesn't exists or is older that the source
  140.         # we copy and remember it
  141.         
  142.         if os.path.exists(dstfile) and \
  143.                 os.stat(dstfile)[8] >= os.stat(path)[8]:
  144.             print 'Not copying', path,'- Up-to-date'
  145.         else:
  146.             print 'Copy', path
  147.             macostools.copy(path, dstfile)
  148.     else:
  149.         dstfile = path
  150.     
  151.     fss = macfs.FSSpec(dstfile)
  152.     creator = fss.GetCreatorType()[0]
  153.     
  154.     if project_files.has_key(creator):
  155.         project_files[creator].append(fss)
  156.     else:
  157.         project_files[creator] = [fss]    
  158.     
  159. def copycwexpfile(path, name):
  160.     """Copy CW export file"""
  161.     global project_files
  162.     
  163.     dstdir = os.path.join(TOP, CWDIR)
  164.     if path[:len(dstdir)] == dstdir:
  165.         return
  166.     srcdir = os.path.split(path)[0]
  167.     srcdir = os.path.split(srcdir)[1]
  168.     if srcdir in CWDIRDIRS:
  169.         if not os.path.exists(dstdir):
  170.             print dstdir
  171.             print 'No CW-project dir, skip', name
  172.             return
  173.         dstfile = os.path.join(dstdir, os.path.join(srcdir, name))
  174.     else:
  175.         if path[-6:] != '.µ.exp':
  176.             return
  177.         dstfile = path[:-6] + '.mu.exp'
  178.     if dstfile[-6:] == '.µ.exp':
  179.         dstfile = dstfile[:-6]+'.mu.exp'
  180.  
  181.     # If the destination doesn't exists or is older that the source
  182.     # we copy and remember it
  183.     
  184.     if os.path.exists(dstfile) and \
  185.             os.stat(dstfile)[8] >= os.stat(path)[8]:
  186.         print 'Not copying', path,'- Up-to-date'
  187.     else:
  188.         print 'Copy', path
  189.         macostools.copy(path, dstfile)    
  190.  
  191. extensions = [
  192. ##    ('.rsrc', binhexit),
  193. ##    ('.gif', binhexit),
  194.     ('.µ', copycwproject),
  195.     ('.prj', copycwproject),
  196.     ('.prj.exp', copycwexpfile),
  197.     ('.µ.exp', copycwexpfile)
  198.     ]
  199.  
  200. def walker(arg, top, names):
  201.     lnames = names[:]
  202.     for n in lnames:
  203.         if n[0] == '(' and n[-1] == ')':
  204.             names.remove(n)
  205.             continue
  206.         for ext, handler in extensions:
  207.             if n[-len(ext):] == ext:
  208.                 name = os.path.join(top, n)
  209.                 handler(name, n)
  210.                 
  211. def dodir(name):
  212.     global TOP, project_files
  213.     TOP = name
  214.     os.path.walk(name, walker, None)
  215.     
  216. ##    for creator in project_files.keys():
  217. ##        hexbincwprojects(creator)
  218.     project_files = {}
  219.                 
  220. def main():
  221.     if len(sys.argv) > 1:
  222.         for dir in sys.argv[1:]:
  223.             dodir(dir)
  224.     elif os.name == 'mac':
  225.         import macfs
  226.         dir, ok = macfs.GetDirectory('Folder to search:')
  227.         if not ok:
  228.             sys.exit(0)
  229.         dodir(dir.as_pathname())
  230.     else:
  231.         print 'Usage: hexbintree dir ...'
  232.         sys.exit(1)
  233.     if os.name == 'mac':
  234.         sys.exit(1)   # Keep window
  235.     else:
  236.         sys.exit(0)
  237.         
  238. if __name__ == '__main__':
  239.     main()
  240.     
  241.